using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.ClinicalTrials
{
    /// <summary>
    /// Provides a summary of all budget financial information
    /// </summary>
    public partial class BudgetSummaryPage : NoCachePage
    {
        private Budget budget;
        private ICachePolicy cachePolicy;

        #region Constants

        private int numberOfTableColumns = 5;
        private int totalColumnIndex = 3;
        private int totalWithOverheadColumnIndex = 4;

        #endregion

        #region Event Handlers

        protected void OnPageLoad(object sender, EventArgs e)
        {
            //ClientSideDirtyStateManagementEnabled = true;
            //ControlIdsToSkipDirtyChecks.Add(save.ClientID);
            reportDownload.EnableInternalExcelLink = true;
            budget = (Budget) ((ICachePolicy) Session[Names.CachePolicyKey]).GetCachedObject(Budget.CacheKey);
            reportDownload.SQLReportName = SSRSRequest.ReportNames.ClinicalTrials.ExternalOutput; //"CT_ExternalOutput";
            reportDownload.InternalSQLReportName = SSRSRequest.ReportNames.ClinicalTrials.InternalOutput; //"CT_InternalOutput";
            if (!IsPostBack)
            {
                LoadBudget();
                InitializeControls();
            }
        }

        protected void OnSave(object sender, EventArgs e)
        {
            if (budget.StatusCode != budgetStatus.SelectedValue)
            {
                budget.StatusCode = budgetStatus.SelectedValue;
                ICachePolicy cachePolicy = (ICachePolicy) Session[Names.CachePolicyKey];
                cachePolicy.Cache("RefreshClinicalTrialBudgetResults", true);
            }
            budget.EnrolledSubjects = Int32.Parse(numberOfPatients.Text);
            budget.Save(DataAccess.GetConnectionString());
            InitializeControls();
        }

        private void OnClose(object sender, EventArgs e)
        {
            Response.Redirect(Settings.GetKeyValue("SubNavigation.ClinicalTrials.BudgetBuilderURL", ""));
        }

        #endregion

        #region Overrides

        /// <summary>
        /// Used to disable controls based on budget status
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            HtmlForm budgetSetupForm = (HtmlForm) Page.FindControl("BudgetSetupForm");

            budget = (Budget) ((ICachePolicy) Session[Names.CachePolicyKey]).GetCachedObject(Budget.CacheKey);

            int accessLevel = budget.AccessLevel;
            string statusCode = budget.StatusCode;

            if (statusCode == ClinicalTrialsConstants.BudgetStatusFinal)
            {
                if (!((CTAccessHelper.IsUserModifyFinalDeleteBudget(accessLevel)) || (CTAccessHelper.IsUserAdministrator(accessLevel))))
                {
                    numberOfPatients.Enabled = save.Enabled = budgetStatus.Enabled = false;
                    foreach (Control formControl in budgetSetupForm.Controls)
                    {
                        DisableControls(formControl);
                    }
                }
            }

            if (!CTAccessHelper.IsUserAdministrator(accessLevel))
            {
                if ((statusCode == ClinicalTrialsConstants.BudgetStatusInProgress) || (statusCode == ClinicalTrialsConstants.BudgetStatusAmended))
                {
                    if (!CTAccessHelper.IsUserModifyPending(accessLevel))
                    {
                        numberOfPatients.Enabled = save.Enabled = budgetStatus.Enabled = false;
                        foreach (Control formControl in budgetSetupForm.Controls)
                        {
                            DisableControls(formControl);
                        }
                    }
                }
            }
        }

        #endregion

        private void DisableControls(Control formControl)
        {
            switch (formControl.GetType().ToString())
            {
                case "System.Web.UI.WebControls.TextBox":
                    (formControl as TextBox).Enabled = false;
                    break;
                case "System.Web.UI.WebControls.CheckBox":
                    (formControl as CheckBox).Enabled = false;
                    break;
                case "System.Web.UI.WebControls.CheckBoxList":
                    (formControl as CheckBoxList).Enabled = false;
                    break;
                case "System.Web.UI.WebControls.RadioButton":
                    (formControl as RadioButton).Enabled = false;
                    break;
                case "System.Web.UI.WebControls.RadioButtonList":
                    (formControl as RadioButtonList).Enabled = false;
                    break;
                case "System.Web.UI.WebControls.Button":
                    if ((formControl.ID == "setup") || (formControl.ID == "staffing")
                        || (formControl.ID == "visits") || (formControl.ID == "otherCosts")
                            || (formControl.ID == "summary") || (formControl.ID == "save"))
                    {
                        (formControl as Button).Enabled = true;
                    }
                    else
                    {
                        (formControl as Button).Enabled = false;
                    }
                    break;
                default:
                    foreach (Control childControl in formControl.Controls)
                    {
                        DisableControls(childControl);
                    }
                    break;
            }
        }

        private void LoadBudget()
        {
            budget = (Budget) cachePolicy.GetCachedObject(Budget.CacheKey);

            if (Session[Keys.IncomingDataKey] != null)
            {
                Hashtable h = (Hashtable) cachePolicy.GetCachedObject(Keys.IncomingDataKey);
                int budgetId = (int) h[Keys.BudgetIdKey];
                if (budgetId == 0)
                {
                    // New Budget
                    budget = new Budget(cachePolicy);
                    budget.StatusCode = "ClinicalTrialBudgetStatusInProgress";
                    UserContext userContext = (UserContext) cachePolicy.GetCachedObject(UserContext.CacheKey);
                    System.Diagnostics.Trace.Assert(userContext != null);
                    budget.OriginatorPersonId = userContext.PersonId;
                    budget.Cache();
                }
                else if (budget == null || budget.Id != budgetId)
                {
                    budget = new Budget(cachePolicy);
                    budget.Load(DataAccess.GetConnectionString(), budgetId);
                    budget.Cache();
                }
                Session.Remove(Keys.IncomingDataKey);
            }
        }

        /// <summary>
        /// Invoked by the download bar when it catches an exception.
        /// </summary>
        /// <param name="sender">Control which raised the event</param>
        /// <param name="e">Argument associated with the event</param>
        private void OnDownloadFailed(object sender, CommandEventArgs e)
        {
            annunciator.Title = "Following error(s) occurred while downloading";
            annunciator.Message = ExceptionReport.GetExceptionInfo((Exception) e.CommandArgument, false);
        }

        #region Private Methods

        private void InitializeControls()
        {
            breadCrumb.Add(
                "Work In Progress",
                "BudgetSetup.aspx", 2);

            ICachePolicy cachePolicy = (ICachePolicy) Application[Names.ApplicationCachePolicyKey];
            RefCodes refCodes = (RefCodes) cachePolicy.GetCachedObject(RefCodes.CacheKey);
            ArrayList budgetStatusCodes = refCodes.GetRefCodes(ClinicalTrialsConstants.BudgetStatusDomain);
            //remove new from the Statuses drop down list
            budgetStatusCodes.RemoveAt(budgetStatusCodes.Count - 1);
            budgetStatus.DataSource = budgetStatusCodes;
            budgetStatus.DataTextField = "Meaning";
            budgetStatus.DataValueField = "Code";
            budgetStatus.DataBind();
            budgetStatus.Attributes["onchange"] = "OnStatusChanged( this );";

            budgetStatus.SelectedValue = budget.StatusCode;

            if (budget.StatusCode == ClinicalTrialsConstants.BudgetStatusFinal || budget.StatusCode == ClinicalTrialsConstants.BudgetStatusAmended)
            {
                budgetStatus.Items.Remove(new ListItem("In Progress", ClinicalTrialsConstants.BudgetStatusInProgress));
            }
            if (budget.StatusCode == ClinicalTrialsConstants.BudgetStatusInProgress)
            {
                budgetStatus.Items.Remove(new ListItem("Amended", ClinicalTrialsConstants.BudgetStatusAmended));
            }

            numberOfPatients.Text = budget.EnrolledSubjects.ToString();

            decimal[] patientRelatedTotals = {0.00M, 0.00M, 0.00M, 0.00M};
            decimal otherCharges = 0.00M;
            decimal otherChargesWithOverhead = 0.00M;

            SqlParameter[] args = DataAccess.BuildSqlParameterArray("@budgetId", SqlDbType.Int, budget.Id);
            SqlDataReader reader = DataAccess.ExecuteReader(DataAccess.GetConnectionString(), "GetClinicalTrialBudgetTotals", args);
            do
            {
                while (reader.Read())
                {
                    TableRow tr = new TableRow();
                    TableCell tdItemName = new TableCell();
                    tdItemName.Text = reader.GetString(0);
                    tr.Cells.Add(tdItemName);
                    for (int i = 1; i < numberOfTableColumns; ++i)
                    {
                        TableCell td = new TableCell();
                        object o = reader[i];
                        // In the "OtherCosts" row, two of the columns are null
                        if (o != DBNull.Value)
                        {
                            decimal amount = reader.GetDecimal(i);
                            td.Text = String.Format("{0:c}", amount);

                            if (tdItemName.Text != "Tasks - Total")
                            {
                                patientRelatedTotals[i - 1] += amount;
                            }
                        }
                        td.CssClass = "Label";
                        tr.Cells.Add(td);
                    }
                    tasksRows.Controls.Add(tr);
                    if (reader[1] == DBNull.Value && reader[totalColumnIndex] != DBNull.Value)
                    {
                        otherCharges = reader.GetDecimal(totalColumnIndex);
                        patientRelatedTotals[2] -= otherCharges;
                        otherChargesWithOverhead = reader.GetDecimal(totalWithOverheadColumnIndex);
                        patientRelatedTotals[3] -= otherChargesWithOverhead;
                    }
                }
            } while (reader.NextResult());
            TableRow totalsRow = new TableRow();
            TableCell totalsTd = new TableCell();
            totalsTd.Text = "Total Patient Related Charges";
            totalsRow.Cells.Add(totalsTd);
            for (int i = 0; i < numberOfTableColumns - 1; ++i)
            {
                totalsTd = new TableCell();
                totalsTd.Text = patientRelatedTotals[i].ToString();
                totalsTd.CssClass = "Label";
                totalsRow.Cells.Add(totalsTd);
            }
            tasksRows.Controls.AddAt(tasksRows.Controls.Count - 1, totalsRow);

            totalsRow = new TableRow();
            totalsTd = new TableCell();
            totalsTd.Text = "Total Study Charges";
            totalsTd.ColumnSpan = 3;
            totalsRow.Cells.Add(totalsTd);
            totalsTd = new TableCell();
            totalsTd.Text = (patientRelatedTotals[2] + otherCharges).ToString();
            totalsTd.CssClass = "Label";
            totalsRow.Cells.Add(totalsTd);
            totalsTd = new TableCell();
            totalsTd.Text = (patientRelatedTotals[3] + otherChargesWithOverhead).ToString();
            totalsTd.CssClass = "Label";
            totalsRow.Cells.Add(totalsTd);

            tasksRows.Controls.Add(totalsRow);
        }

        #endregion

        #region Web Form Designer generated code

        ///<summary>Initializes components used by the page.</summary>
        protected override void OnInit(EventArgs e)
        {
            cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);
            this.reportDownload.FailedAction += new CommandEventHandler(OnDownloadFailed);
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion
    }
}